package com.regent.central.bill.common;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.chrono.ChronoZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * Created by wizzer on 2016/6/24.
 */
public class DateUtil {
    public static final String DATE_PATTERN1 = "yyyy年MM月dd日 HH时mm分ss秒";
    public static final String DATE_PATTERN2 = "yy/MM/dd HH:mm";
    public static final String DATE_PATTERN3 = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_PATTERN4 = "yyyy年MM月dd日 HH时mm分ss秒  E";
    public static final String DATE_PATTERN5 = "一年中的第D天 一年中第w个星期 一月中第W个星期 在一天中k时 z时区";
    public static final String DATE_PATTERN6 = "dd/MMM/yyyy:hh:mm:ss z";
    public static final String FORMAT_TIMESTANP = "yyyy-MM-dd HH:mm:ss";
    public static final String FORMAT_DATE = "yyyy-MM-dd";
    private static final Locale DEFAULT_LOCALE = Locale.CHINA;
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 获取当前时间(HH:mm:ss)
     *
     * @return
     */
    public static String getDate() {
        return DateFormatUtils.format(new Date(), "yyyy-MM-dd", DEFAULT_LOCALE);
    }

    /**
     * 获取当前时间(HH:mm:ss)
     *
     * @return
     */
    public static String getTime() {
        return DateFormatUtils.format(new Date(), "HH:mm:ss", DEFAULT_LOCALE);
    }

    /**
     * 获取当前时间(yyyy-MM-dd HH:mm:ss)
     *
     * @return
     */
    public static String getDateTime() {
        return DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
    }

    /**
     * 转换日期格式(yyyy-MM-dd HH:mm:ss)
     *
     * @param date
     * @return
     */
    public static String formatDateTime(Date date) {
        if (date == null) return "";
        return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
    }

    /**
     * 转换日期格式(yyyy-MM-dd HH:mm:ss)
     *
     * @param date
     * @param f
     * @return
     */
    public static String format(Date date, String f) {
        if (date == null) return "";
        return DateFormatUtils.format(date, f, DEFAULT_LOCALE);
    }

    /**
     * 时间戳日期
     *
     * @param time
     * @return
     */
    public static String getDate(long time) {
        return DateFormatUtils.format(new Date(time * 1000), "yyyy-MM-dd HH:mm:ss", DEFAULT_LOCALE);
    }

    /**
     * 时间戳日期
     *
     * @param time
     * @param f
     * @return
     */
    public static String getDate(long time, String f) {
        return DateFormatUtils.format(new Date(time * 1000), f, DEFAULT_LOCALE);
    }

    /**
     * 通过字符串时间获取时间戳
     *
     * @param date
     * @return
     */
//    public static int getTime(String date) {
//        try {
//            return (int) (sdf.parse(date).getTime() / 1000);
//        } catch (ParseException e) {
//            return 0;
//        }
//    }


    /**
     * 将长整型装换为指定格式的字符串
     *
     * @param sysDate
     * @param pattern
     * @return
     */
    public static String formart(Long sysDate, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = new Date(sysDate);
        String reInfo = sdf.format(date);
        return reInfo;
    }

    /**
     * 将字符串转化为时间格式(月份为英文格式)
     *
     * @param date
     * @param patterns
     * @return
     */
    public static Date formartToDate(String date, String... patterns) {
        Date reInfo = null;
        for (String pattern : patterns) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern, new Locale("eglish"));
            try {
                reInfo = sdf.parse(date);
                break;
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return reInfo;
    }

    public static Date formatToDateDefault(String date) {
        return formartToDate(date, "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
    }
    /**
     * 将两个时间的前后合并, 前面的取年月日, 后面的取时分秒
     *
     * @param date 取年月日的日期
     * @param time 取时分秒的日期
     * @return 合并后的日期
     */
    public static Date merge(Date date, Date time) {
        if (date == null || time == null) {
            return new Date();
        }
        Calendar calendarTime = DateUtil.dataToCalendar(time);
        Calendar calendarDate = DateUtil.dataToCalendar(date);
        calendarDate.set(Calendar.HOUR_OF_DAY, calendarTime.get(Calendar.HOUR_OF_DAY));
        calendarDate.set(Calendar.MINUTE, calendarTime.get(Calendar.MINUTE));
        calendarDate.set(Calendar.SECOND, calendarTime.get(Calendar.SECOND));
        return calendarDate.getTime();
    }

    public static Calendar dataToCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 判断是否在用一个月，如果是，就返回true
     *
     * @param preDate
     * @return
     */
    public static boolean isSameMouth(Date preDate) {
        if (preDate == null) {
            return false;
        } else {
            Calendar nowC = Calendar.getInstance();
            Calendar preDateC = Calendar.getInstance();
            preDateC.setTime(preDate);
            if (nowC.get(Calendar.YEAR) == preDateC.get(Calendar.YEAR) && nowC.get(Calendar.MONTH) == preDateC.get(Calendar.MONTH)) {
                return true;
            } else {
                return false;
            }
        }

    }

    /**
     * 字符串转换成日期格式
     *
     * @param pattern 日期格式
     * @param str     字符串
     * @return
     */
    public static Date getDateForMat(String pattern, String str) {
        Date date = new Date();
        if (str != null && !"".equals(str)) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                date = sdf.parse(str);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            date = null;
        }
        return date;
    }

    /**
     * 获得当前日期与本周一相差的天数
     *
     * @return
     */
    public static int getTuesdayPlus() {
        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            return -6;
        } else {
            return 3 - dayOfWeek;
        }
    }

    /**
     * 取得当前时间的上一个礼拜二的时间
     *
     * @return
     */
    public static Date getPreviousTuesday() {
        int weeks = 0;
        weeks--;
        int mondayPlus = getTuesdayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * weeks);
        Date monday = currentDate.getTime();
        return monday;
    }

    /**
     * 排行榜使用，获取上周二到这周二之间的时间
     *
     * @return
     */
    public static String getStartTimeAndEndTime() {
        String startTime = "";
        String endTime = "";
        try {
            Date date = getPreviousTuesday();
            startTime = date2String(date, "yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_YEAR, 7);
            endTime = date2String(calendar.getTime(), "yyyy-MM-dd");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "between to_date('" + startTime + "','yyyy-MM-dd') and to_date('" + endTime + "','yyyy-MM-dd')";
    }

    public static String getTodayBeginTimeAndEndTime() {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,S");
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        System.out.println(sf.format(todayStart.getTime()));
        return "";
    }

    /**
     * 时间格式转换成字符串
     *
     * @param date    日前
     * @param pattern 要转换的字符格式
     * @return
     */
    public static String date2String(Date date, String pattern) {
        if (pattern != null && !"".equals(pattern) && date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            return sdf.format(date);
        } else {
            return "";
        }
    }

    /**
     * 判断当前时间是否在给定的一天的时间范围内
     *
     * @return
     */
    public static boolean isInTimeInterval() {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        if (hour > 7 && hour < 23) {
            return true;
        } else {
            return false;
        }
    }

    public static Date getDate(String str) {
        try {
            return new SimpleDateFormat("yyyy-MM-dd").parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Date();
    }


    /**
     * 获取一周中的第一天
     */
    public static String getFirstDateOfWeek(Date d) {
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        int dd = c.get(GregorianCalendar.DAY_OF_WEEK);
        if (dd == 1)
            dd = 7;
        else if (dd > 1)
            dd = dd - 1;
        c.add(Calendar.DATE, 1 - dd);
        String date = c.get(Calendar.YEAR) + "-" + towStr(1 + c.get(Calendar.MONTH)) + "-" + towStr(c.get(Calendar.DATE));
        return date;
    }

    /**
     * 获取一周中的最后一天
     */
    public static String getLastDateOfWeek() {
        Calendar c = Calendar.getInstance();
        int dd = c.get(GregorianCalendar.DAY_OF_WEEK);
        if (dd == 1)
            dd = 7;
        else if (dd > 1)
            dd = dd - 1;
        c.add(Calendar.DATE, 7 - dd);
        String date = c.get(Calendar.YEAR) + "-" + towStr(1 + c.get(Calendar.MONTH)) + "-" + towStr(c.get(Calendar.DATE));
        return date;
    }

    public static String towStr(int n) {
        if (n < 10)
            return "0" + n;
        else
            return "" + n;
    }

    /**
     * 获取两个时间所差天数
     *
     * @param begin 起始时间
     * @param end   结束时间
     */
    public static int isPssFixedDay(Date begin, Date end) {
        Calendar beginTime = Calendar.getInstance();
        beginTime.setTime(begin);
        Calendar endTime = Calendar.getInstance();
        endTime.setTime(end);

        long difTime = (beginTime.getTimeInMillis() - endTime.getTimeInMillis()) / (1000 * 60 * 60 * 24);

        beginTime = null;
        endTime = null;
        return (int) difTime;
    }

    /**
     * 获取两个时间间隔（秒数不同的时候取秒的差值;分钟不同取分钟的差值;小时不同取小时的差值;天数不同取天数的差值;月份不同取月份的差值;
     * 年份不同取年份的差值）
     *
     * @param begin 起始时间
     * @param end   结束时间
     */
    public static String getDifTime(Date begin, Date end) {
        int difTime = 0;
        String rtnVal = null;
        Calendar beginTime = Calendar.getInstance();
        beginTime.setTime(begin);
        Calendar endTime = Calendar.getInstance();
        endTime.setTime(end);
        if (date2String(begin, "yyyy-MM-dd HH:mm").equals(date2String(end, "yyyy-MM-dd HH:mm"))) {
            difTime = endTime.get(Calendar.SECOND) - beginTime.get(Calendar.SECOND);
            rtnVal = String.valueOf(difTime) + "秒";
        } else if (date2String(begin, "yyyy-MM-dd HH").equals(date2String(end, "yyyy-MM-dd HH"))) {
            difTime = endTime.get(Calendar.MINUTE) - beginTime.get(Calendar.MINUTE);
            rtnVal = String.valueOf(difTime) + "分";
        } else if (date2String(begin, "yyyy-MM-dd").equals(date2String(end, "yyyy-MM-dd"))) {
            difTime = endTime.get(Calendar.HOUR) - beginTime.get(Calendar.HOUR);
            rtnVal = String.valueOf(difTime) + "时";
        } else if (date2String(begin, "yyyy-MM").equals(date2String(end, "yyyy-MM"))) {
            difTime = endTime.get(Calendar.DATE) - beginTime.get(Calendar.DATE);
            rtnVal = String.valueOf(difTime) + "天";
        } else if (date2String(begin, "yyyy").equals(date2String(end, "yyyy"))) {
            difTime = endTime.get(Calendar.MONTH) - beginTime.get(Calendar.MONTH);
            rtnVal = String.valueOf(difTime) + "月";
        } else {
            difTime = endTime.get(Calendar.YEAR) - beginTime.get(Calendar.YEAR);
            rtnVal = String.valueOf(difTime) + "年";
        }
        beginTime = null;
        endTime = null;
        return rtnVal;
    }

    /**
     * 得到时间间隔的时间
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static String getTime(String time) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String current = format.format(new Date());
        long date1 = format.parse(current).getTime();
        long date2 = format.parse(time).getTime();

        System.out.println(current);
        System.out.println(time);
        long jiange = 0;// 间隔时间(毫秒)
        if (date1 > date2) {
            jiange = date1 - date2;
        } else {
            jiange = date2 - date1;
        }
        jiange = jiange / (60 * 60 * 1000);
        return Long.toString(jiange);

    }

    /**
     * 将日期字符串转化为 java.util.Date
     *
     * @param dateString 日期字符串
     * @param fmt
     * @return
     */
    public static Date stringToDate(String dateString, String fmt) {
        if (dateString == null || "".equals(dateString.trim())) {
            return null;
        }

        SimpleDateFormat sdf = new SimpleDateFormat(fmt);
        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        return date;
    }

    /**
     * 将日期字符串转化为 java.util.Date, 格式为 yyyy-MM-dd
     *
     * @param dateString 日期字符串
     * @return
     */
    public static Date stringToDate(String dateString) {
        return stringToDate(dateString, FORMAT_DATE);
    }

    /**
     * @param time 传入的时间
     * @return 拼接后的字符串
     * @desc 根据传入的时间，拼接展示的字符串
     * @author zhangjian
     * @time 2011-5-22
     */
    public static String getDisplayTimeFormat(Date time) {
        long startTime = time.getTime();
        long endTime = new Date().getTime();
        if (endTime < startTime) {
            return "";
        }
        // 相差的秒
        long poor = (endTime - startTime) / 1000;
        if (poor < 60) {
            return "大约" + poor + "秒前";
        }
        // 相差的分钟
        poor = poor / 60;
        if (poor < 60) {
            return "大约" + poor + "分钟前";
        }
        // 相差的小时
        poor = poor / 60;
        if (poor < 24) {
            return "大约" + poor + "小时前";
        }
        // 相差的天数
        poor = poor / 24;
        if (poor < 31) {
            return "大约" + poor + "天前";
        }
        // 相差的月数
        poor = poor / 31;
        if (poor < 12) {
            return "大约" + poor + "月前";
        }
        return "一年前";
    }

    /**
     * 得到当前时间(yyyy-mm-dd hh:MM:ss)
     *
     * @return
     */
    public static String getCurrentTime() {
        Date date = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");
        return format.format(date);
    }


    /**
     * 增减分钟数
     *
     * @param date
     * @param minuteCount
     * @return
     */
    public static Date getNextDateByMinuteCount(Date date, int minuteCount) {
        Calendar scalendar = Calendar.getInstance();
        scalendar.setTime(date);
        scalendar.add(Calendar.MINUTE, minuteCount);
        return scalendar.getTime();
    }


    public static String getDateByday2(String datetime, int datnum, String rule) {
        SimpleDateFormat sdf = new SimpleDateFormat(rule);
        // 将字符串的日期转为Date类型，ParsePosition(0)表示从第一个字符开始解析
        Date date = sdf.parse(datetime, new ParsePosition(0));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // add方法中的第二个参数n中，正数表示该日期后n天，负数表示该日期的前n天
        calendar.add(Calendar.DATE, datnum);
        Date date1 = calendar.getTime();
        String out = sdf.format(date1);
        return out;
    }

    /**
     * 根据传入的日期返回传入的日期加上当前系统时间组成的日期时间
     *
     * @param date    日期
     * @param pattern 日期格式
     * @return
     * @author xx
     */
    public static Date dateToDateTime(Date date, String pattern) {
        if (pattern != null && !"".equals(pattern) && date != null) {
            String dateStr = date2String(date, "yyyy-MM-dd");
            String timeStr = getTime();
            return formartToDate(dateStr + " " + timeStr, pattern);
        } else {
            return null;
        }
    }

    /**
     * LocalDate 转 Date
     */
    public static Date localDateToDate(LocalDate localDate) {
        ZoneId zoneId = ZoneId.systemDefault();
        ChronoZonedDateTime<LocalDate> zonedDateTime = localDate.atStartOfDay(zoneId);
        return Date.from(zonedDateTime.toInstant());
    }

    public static LocalDate dateToLocalDate(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate();
    }

}
